From 12404bc88dc418d62a993e079db77d0f887b9421 Mon Sep 17 00:00:00 2001 From: robertl Date: Mon, 23 Nov 2009 18:43:08 +0000 Subject: [PATCH] Add read support for Gopal 4.8, 5.0 extended date fields. --- gopal.c | 42 +++++++---- reference/gopal-11-gpx.gpx | 139 +++++++++++++++++++++++++++++++++++++ reference/gopal-11.trk | 7 ++ testo | 3 + xmldoc/formats/gopal.xml | 3 + 5 files changed, 181 insertions(+), 13 deletions(-) create mode 100644 reference/gopal-11-gpx.gpx create mode 100644 reference/gopal-11.trk diff --git a/gopal.c b/gopal.c index 7e1eeded7..01b2151ca 100644 --- a/gopal.c +++ b/gopal.c @@ -89,11 +89,6 @@ int gopal_check_line(char *line) c++; i++; } - if (i != 8) - { - snprintf(tmp,sizeof(tmp),"\"%s\"\n",line); - fprintf(stderr,"%s",tmp); - } return i; } @@ -156,11 +151,11 @@ gopal_rd_init(const char *fname) } // in buff we should now have something wich looks like a valid date starting with YYYYMMDD ck = (char *)strptime(buff, "%Y%m%d", &filenamedate); - if (((ck == NULL) || (*ck != '\0') )&&!(optdate)) - fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"optdate\" switch!\n", buff); - else if (filenamedate.tm_year < 70) - fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", buff); - tx= mkgmtime(&filenamedate); + // if (((ck == NULL) || (*ck != '\0') )&&!(optdate)) + // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); + // /* else */ if (filenamedate.tm_year < 70) + // fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", buff); + // tx= mkgmtime(&filenamedate); } } @@ -186,6 +181,7 @@ gopal_read(void) char tbuffer[64]; long_old=0;lat_old=0; strftime(routename,sizeof(routename),"Tracklog %c",localtime(&tx)); + struct tm tm2; route = route_head_alloc(); route->rte_name=xstrdup(routename); @@ -194,11 +190,18 @@ gopal_read(void) line=0; while ((buff = gbfgetstr(fin))) { + int nfields; + unsigned long microsecs; if ((line == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); str = buff = lrtrim(buff); if (*buff == '\0') continue; - if (gopal_check_line(buff)!=8)continue; + nfields = gopal_check_line(buff); + if ((nfields != 8) && (nfields != 11))continue; + // Old format. Hassle for date. + if ((nfields == 8) && (tx == 0)) { + // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); + } wpt = waypt_new(); column = -1; @@ -211,7 +214,9 @@ gopal_read(void) switch(column) { case 0: /* "-" */ /* unknown fields for the moment */ - //sscanf(c, "%llu", &wpt->microseconds); + sscanf(c, "%lu", µsecs); + wpt->microseconds += microsecs % 1000000; + wpt->creation_time += microsecs / 1000000; break; case 1: /* Time UTC */ sscanf(c,"%lf",&hmsd); @@ -271,7 +276,18 @@ gopal_read(void) case 8: /* number of sats */ sscanf(c, "%d", &wpt->sat); break; - + // Somewhere around mid/late 2009, these files started + // seeing 11 fields. + case 9: + memset(&tm2, 0, sizeof(tm2)); + if (!strptime(c, "%Y%m%d", &tm2)) { + fatal ("Bad date '%s'.\n", c); + } + wpt->creation_time += mkgmtime(&tm2); + break; + case 10: // Unknown. Ignored. + case 11: // Bearing. Ignored. + break; } c = csv_lineparse(NULL, ",", "", column++); } diff --git a/reference/gopal-11-gpx.gpx b/reference/gopal-11-gpx.gpx new file mode 100644 index 000000000..849bbd0f9 --- /dev/null +++ b/reference/gopal-11-gpx.gpx @@ -0,0 +1,139 @@ + + + + + + 341.950000 + + RPT001 + RPT001 + RPT001 + 2d + 11 + 0.766000 + + + 341.990000 + + RPT002 + RPT002 + RPT002 + 2d + 11 + 0.766000 + + + 341.813000 + + RPT003 + RPT003 + RPT003 + 2d + 10 + 0.832000 + + + 341.493000 + + RPT004 + RPT004 + RPT004 + 2d + 11 + 0.766000 + + + 341.150000 + + RPT005 + RPT005 + RPT005 + 2d + 11 + 0.766000 + + + 340.210000 + + RPT006 + RPT006 + RPT006 + 2d + 11 + 0.766000 + + + 339.163000 + + RPT007 + RPT007 + RPT007 + 2d + 11 + 0.766000 + + + Tracklog Wed Dec 31 18:00:00 1969 + + 341.950000 + + RPT001 + 2d + 11 + 0.766000 + + + 341.990000 + + RPT002 + 2d + 11 + 0.766000 + + + 341.813000 + + RPT003 + 2d + 10 + 0.832000 + + + 341.493000 + + RPT004 + 2d + 11 + 0.766000 + + + 341.150000 + + RPT005 + 2d + 11 + 0.766000 + + + 340.210000 + + RPT006 + 2d + 11 + 0.766000 + + + 339.163000 + + RPT007 + 2d + 11 + 0.766000 + + + diff --git a/reference/gopal-11.trk b/reference/gopal-11.trk new file mode 100644 index 000000000..f3d8da67a --- /dev/null +++ b/reference/gopal-11.trk @@ -0,0 +1,7 @@ +38528677, 213232, 8.232662, 50.307048, 341.95, 180.227, 2, 0.766000, 11, 20091106, 0, 300 +38529696, 213233, 8.232442, 50.307475, 341.99, 179.174, 2, 0.766000, 11, 20091106, 0, 298 +38530720, 213234, 8.232223, 50.307902, 341.813, 179.203, 2, 0.832000, 10, 20091106, 0, 297 +38531752, 213235, 8.232000, 50.308332, 341.493, 181.152, 2, 0.766000, 11, 20091106, 0, 295 +38532669, 213236, 8.231770, 50.308765, 341.15, 183.765, 2, 0.766000, 11, 20091106, 0, 293 +38533696, 213237, 8.231532, 50.309198, 340.21, 183.95, 2, 0.766000, 11, 20091106, 0, 292 +38534714, 213238, 8.231283, 50.309623, 339.163, 178.342, 2, 0.766000, 11, 20091106, 0, 291 diff --git a/testo b/testo index 34a4cad0e..472b5bdb5 100755 --- a/testo +++ b/testo @@ -1425,6 +1425,9 @@ gpsbabel -i gopal -f ${TMPDIR}/${GoPalName}.tst -o gpx -F ${TMPDIR}/${GoPalName gpsbabel -i gpx -f ${TMPDIR}/${GoPalName}.im2 -o gopal -F ${TMPDIR}/${GoPalName}.tst3 compare ${TMPDIR}/${GoPalName}.tst2 ${TMPDIR}/${GoPalName}.tst3 +# Gopal with 11 fields is slightly more sane. +gpsbabel -i gopal -f reference/gopal-11.trk -o gpx -F ${TMPDIR}/gopal-11-gpx.gpx +compare ${TMPDIR}/gopal-11-gpx.gpx reference/gopal-11-gpx.gpx # # Height filter diff --git a/xmldoc/formats/gopal.xml b/xmldoc/formats/gopal.xml index 41c0fcbda..2e692e4a5 100644 --- a/xmldoc/formats/gopal.xml +++ b/xmldoc/formats/gopal.xml @@ -30,6 +30,9 @@ Conversions from gopal into any other format are a bit lossy concerning the firs and is simply discarded while reading. If written, there will be a time_t value from the current (computed) timestamp. +Somehwere around Gopal 4.8 or 5.0, Electrobit added three more fields to the end of this format. They are, in order, date (which eliminates most of the silliness above), an unknonw field, and a bearing. GPSBabel now reads the date and ignores the other two. We don't yet write these three fields for compatibility with earlier versions. + + Filtering out invalid data points is handled by the options 'clean', 'minspeed' and 'maxspeed'. For each datapoint the speed needed to come the from the last valid point is -- 2.30.2